#include "Face.h"
#include "ui_Face.h"
#include "Mainpage.h"
#include <QDir>
#include <QFileInfo>
#include <QDateTime>
#include <QMessageBox>
#include <QThread>
#include <QBitmap>
#include <QStyleOption>
#include "mymessagebox.h"

Face::Face(const QString &id, Mainpage *mainpage, QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Face)
    , mainpageWindow(mainpage)
    , employeeId(id)  // 通过构造函数传递工号
    , cap(0)  // 初始化摄像头，0 表示电脑自带的摄像头
    , tcpSocket(new QTcpSocket(this))  // 初始化 TCP 套接字
{
    ui->setupUi(this);

    // 隐藏原生标题栏
    setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);

    // 防止窗口背景透明
    setAttribute(Qt::WA_TranslucentBackground, false);

    // 加载人脸检测分类器
    if (!cascada.load("D:\\Qt_project\\Client\\haarcascade_frontalface_alt2.xml")) {
        qDebug() << "无法加载人脸分类器";
        return;
    }

    // 连接到服务器
    tcpSocket->connectToHost("127.0.0.1", 12349);
    if (!tcpSocket->waitForConnected(3000)) {
        qDebug() << "连接到服务器失败";
        return;
    }
}

Face::~Face()
{
    delete ui;
}

// 实现窗口拖动功能
void Face::mousePressEvent(QMouseEvent *event)
{
    // 检查是否点击了自定义标题栏
    if (event->button() == Qt::LeftButton && event->pos().y() <= 60) {
        m_isTitleBarClicked = true;
        m_dragPosition = event->globalPos() - frameGeometry().topLeft();
        event->accept();
    } else {
        m_isTitleBarClicked = false;
        // 让事件继续传播，确保其他控件能响应点击事件
        QWidget::mousePressEvent(event);
    }
}

void Face::mouseMoveEvent(QMouseEvent *event)
{
    // 只有在点击了标题栏之后才允许拖动
    if (m_isTitleBarClicked && (event->buttons() & Qt::LeftButton)) {
        move(event->globalPos() - m_dragPosition);
        event->accept();
    } else {
        // 让事件继续传播，确保其他控件能响应移动事件
        QWidget::mouseMoveEvent(event);
    }
}

void Face::paintEvent(QPaintEvent *event)
{
    // 1. 绘制样式（QSS）
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); // 绘制样式

    // 2. 设置掩码，约定 painter 绘制区域
    QBitmap bmp(this->size());
    bmp.fill(Qt::white); // 填充 bitmap

    QPainter painter(&bmp);
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::black); // 掩码值
    painter.drawRoundedRect(bmp.rect(), 30, 30); // 在 bitmap 中绘制圆角矩形

    // 设置掩码以确定本控件可绘制区域
    setMask(bmp);

    // 调用基类的 paintEvent
    QWidget::paintEvent(event);
}

void Face::on_returnButton_clicked()
{
    this->close();
    mainpageWindow->show();
}


void Face::on_start_clicked()
{
    // 如果摄像头没有打开，重新打开摄像头
    if (!cap.isOpened()) {
        cap.open(0);  // 打开默认摄像头
        if (!cap.isOpened()) {
            qDebug() << "无法打开摄像头";
            return;
        }
    }

    // 重置照片编号，保证覆盖之前的10张照片
    pic_num = 1;

    // 初始化定时器
    if (!timer) {
        timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, &Face::processFrameAndUpdate);
    }

    timer->start(100);  // 每 100ms 处理一帧
}


void Face::on_yes_clicked()
{
    if (!tcpSocket->isOpen()) {
        qDebug() << "TCP 连接尚未打开";
        return;
    }

    // 获取当前时间
    QDateTime currentTime = QDateTime::currentDateTime();
    QString currentTimeStr = currentTime.toString("yyyy-MM-dd HH:mm:ss");

    // 准备要发送的数据：工号和当前时间，以 "DATA:" 为前缀标识
    QString dataToSend = "DATA:" + employeeId + "|" + currentTimeStr;

    // 发送工号和当前时间到服务器
    tcpSocket->write(dataToSend.toUtf8());
    tcpSocket->flush();

    // 等待服务器回应
    connect(tcpSocket, &QTcpSocket::readyRead, this, [=]() {
        QByteArray response = tcpSocket->readAll();
        if (response == "SUCCESS") {
            // QMessageBox::information(this, "成功", "申请成功");
            MyMessageBox msgBox;
            msgBox.setWindowTitle("成功");
            msgBox.setText("申请成功");
            msgBox.setButton("确定");
            msgBox.exec();

            // 开始发送文件
            sendFiles();
        } else {
            // QMessageBox::warning(this, "错误", "申请失败");
            MyMessageBox msgBox;
            msgBox.setWindowTitle("错误");
            msgBox.setText("申请失败");
            msgBox.setButton("确定");
            msgBox.exec();
        }
    });

    qDebug() << "发送工号和时间数据完毕：" << dataToSend;
}

void Face::sendFiles()
{
    // 获取保存的图片文件路径
    QString dirPath = QDir::currentPath() + "/" + employeeId;
    QDir dir(dirPath);
    QStringList fileList = dir.entryList(QStringList() << "*.jpg", QDir::Files);

    // 遍历文件，依次发送到服务器
    foreach (QString filename, fileList) {
        QFile file(dirPath + "/" + filename);
        if (file.open(QIODevice::ReadOnly)) {
            // 获取文件内容并进行 Base64 编码
            QByteArray fileContent = file.readAll();
            QString encodedContent = QString::fromUtf8(fileContent.toBase64());

            // 准备发送文件名和文件内容，包括 employeeId
            QString fileToSend = "FILE:" + employeeId + "|" + filename + "|" + encodedContent;

            // 发送文件到服务器
            tcpSocket->write(fileToSend.toUtf8());
            tcpSocket->flush();

            qDebug() << "发送文件：" << filename << "工号：" << employeeId;

            file.close();

            // 每次发送文件后延迟100毫秒
            QThread::msleep(100);
        }
    }

    qDebug() << "文件发送完毕";
    // QMessageBox::information(this, "提示", "文件发送完毕");
    MyMessageBox msgBox;
    msgBox.setWindowTitle("提示");
    msgBox.setText("文件发送完毕");
    msgBox.setButton("确定");
    msgBox.exec();
}


void Face::processFrameAndUpdate()
{
    cv::Mat frame, frame_gray, myFace;
    cap >> frame;  // 读取摄像头的当前帧
    if (frame.empty()) {
        qDebug() << "摄像头未捕获到帧";
        return;
    }

    std::vector<cv::Rect> faces;
    cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);  // 转为灰度图

    // 检测人脸
    cascada.detectMultiScale(frame_gray, faces, 1.1, 4, cv::CASCADE_SCALE_IMAGE, cv::Size(70, 70), cv::Size(1000, 1000));
    qDebug() << "检测到人脸个数：" << faces.size();

    // 圈出检测到的人脸
    for (size_t i = 0; i < faces.size(); i++) {
        cv::rectangle(frame, faces[i], cv::Scalar(255, 0, 0), 2, 8, 0);
    }

    // 当检测到一个人脸时，拍照保存
    if (faces.size() == 1) {
        cv::Mat faceROI = frame_gray(faces[0]);
        cv::resize(faceROI, myFace, cv::Size(92, 112));

        QString currentPath = QDir::currentPath(); // 获取当前目录的路径
        QString dirPath = currentPath + "/" + employeeId; // 组合新的目录路径

        QDir dir(dirPath);
        if (!dir.exists()) { // 如果目录不存在
            if (!dir.mkpath(".")) { // 尝试创建目录
                // 如果创建失败
                qDebug() << "Failed to create directory: " << dirPath;
            } else {
                // 目录创建成功
                qDebug() << "Directory created: " << dirPath;
            }
        } else {
            // 目录已存在
            qDebug() << "Directory already exists: " << dirPath;
        }

        QString filename = QString(".\\%1\\%2.jpg").arg(employeeId).arg(pic_num);
        cv::imwrite(filename.toStdString(), myFace);
        qDebug() << "保存图片：" << filename;

        pic_num++;
        if (pic_num == 11) {
            timer->stop();  // 拍满10张后停止

            // 释放摄像头资源
            cap.release();
            qDebug() << "摄像头已关闭";
        }
    }

    // 将处理后的视频帧显示在 QLabel 上
    cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);  // 转为 RGB 格式以便 Qt 显示
    QImage qimg((uchar*)frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
    ui->face->setPixmap(QPixmap::fromImage(qimg).scaled(ui->face->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
}
